package service

import (
	"LibraryManagementSys/global"
	"LibraryManagementSys/gorm/dbm"
	"LibraryManagementSys/internal/repository/dao"
	"LibraryManagementSys/model"
	"LibraryManagementSys/model/dto"
	"LibraryManagementSys/model/request"
	"LibraryManagementSys/pkg/util"
	"context"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"time"
)

var UserService = &userService{}

type userService struct{}

// Register 用户注册业务处理
// @receiver userService
// @return   error
func (userService) Register(param *dto.RegisterParam) error {
	generateFromPassword, err := util.GenerateFromPassword(param.Password)
	if err != nil {
		zap.S().Errorf("密码加密失败: %s\n", err)
		return err
	}

	user := &dbm.User{
		Username:   param.Username,
		Password:   generateFromPassword,
		Sex:        param.Sex,
		Phone:      param.Phone,
		Email:      param.Email,
		CreateTime: time.Now(),
		UpdateTime: time.Now(),
	}

	err = dao.UserDao.Insert(user)
	if err != nil {
		fmt.Println("insert失败", err)
		return err
	}
	return nil
}

// Login 登录
// @receiver userService
// @return   token
// @return   err
func (userService) Login(param *dto.LoginParam) (token string, err error) {
	if param == nil {
		zap.L().Info("登录信息为空")
		return "", errors.New("登录信息为空")
	}

	fmt.Println(param)

	user, err := dao.UserDao.LoadUserByUsername(param.Username)
	if err != nil {
		zap.S().Errorf("从数据库中查询用户名为: %s 的用户失败: %s", param.Username, err)
		return "", err
	}

	fmt.Println(user)

	err = util.CompareHashAndPassword(user.Password, param.Password)
	if err != nil {
		zap.S().Errorf("用户名密码错误: %s", err)
		return "", err
	}

	fmt.Println("==========")

	generateToken, err := util.GenerateToken(user.Username)
	if err != nil {
		zap.S().Errorf("根据用户名生成 token 失败: %s", user.Username)
		fmt.Println(err)
		return "", err
	}

	fmt.Println("generateToken:", generateToken)

	return generateToken, nil
}

func (userService) LoadUserByUsername(username string) (user *dbm.User, err error) {
	return dao.UserDao.LoadUserByUsername(username)
}

func (userService) Logout(token string) error {
	res, err := global.LMS_REDIS.Del(context.TODO(), token).Result()
	if err != nil {
		global.LMS_LOG.Errorf("发生错误! Err: %s", err.Error())
		return err
	}

	if res != 1 {
		return errors.New("退出登录失败！")
	}
	return nil
}

func (userService) UpdateUserRole(roleUr request.UserRole) error {
	err := global.LMS_DB.Model(model.User{}).Where("id = ?", roleUr.Id).Updates(roleUr).Error
	if err != nil {
		return err
	}
	return nil
}
